package com.tangtang.core;

import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.HanyuPinyinVCharType;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;

import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;

public class StringUtil {


    /**
     * 数组连接成字符串
     *
     * @param inputs
     * @param seperator
     * @return
     */
    public static String join(String[] inputs, String seperator) {
        return StringUtils.join(inputs, seperator);
    }


    /**
     * 字符串安全trim()
     *
     * @param input 输入的字符串
     * @return 经过trim的字符串
     */
    public static String trim(String input) {
        if (input == null) return null;
        return input.trim();
    }

    /**
     * 删除结尾的字符
     *
     * @param input
     * @return
     */
    public static String rightTrim(String input) {
        if (input == null || input.trim().length() == 0) {
            return "";
        }
        int position = input.length();
        while (true) {
            char _char = input.charAt(position - 1);
            if (_char == ' ' || _char == ',' || _char == '，' || _char == '|') {
                position--;
            } else {
                break;
            }
        }
        if (position == input.length()) {
            return input;
        } else {
            return input.substring(0, position);
        }
    }

    /**
     * 清除回车
     *
     * @param input
     * @return
     */
    public static String clearBr(String input) {
        if (input == null || input.length() == 0) {
            return "";
        }
        return input.replace("\r\n", "");
    }

    /**
     * 不区分中英文的截字
     *
     * @param input      传入参数
     * @param startIndex 起始位置
     * @param length     截取长度
     * @return
     */
    public static String cutString(String input, int startIndex, int length) {
        if (input == null || input.length() == 0) {
            return "";
        }
        if (startIndex >= 0 && length > 0 && startIndex + length <= input.length()) {
            return input.substring(startIndex, length);
        }
        return input;
    }

    /**
     * 中文字符长度
     *
     * @param input
     * @return
     */
    public static int lengthCN(String input) {
        if (StringUtil.isBlank(input)) {
            return 0;
        }
        int result = input.length();
        for (int i = 0; i < input.length(); i++) {
            if (input.charAt(i) > 0xFF)
                result++;
        }
        return result;
    }

    /**
     * @param input
     * @param length
     * @return
     */
    public static String cutString(String input, int length) {
        return cutString(input, 0, length);
    }

    /**
     * 中英文字符串截取
     *
     * @param input
     * @param len
     * @param tail
     * @return
     */
    public static String cutStringCN(String input, int len, String tail) {
        if (input == null || input.length() == 0) {
            return "";
        }

        int l = input.length();

        for (int i = 0; i < l && i < len; i++) {
            if (input.charAt(i) > 0xFF)
                len--;
        }
        if (l <= len) {
            return input;
        }
        String result = input.substring(0, len);
        return tail == null ? result : result + tail;
    }

    /**
     * 中英文字符串截取
     *
     * @param input
     * @param len
     * @return
     */
    public static String cutStringCN(String input, int len) {
        return cutStringCN(input, len, null);
    }

    /**
     * 转全角的函数(SBC case) To全角字符串(半角转全角) 全角空格为12288,半角空格为32
     * 其他字符半角(33-126)与全角(65281-65374)的对应关系是：均相差65248
     *
     * @param input
     * @return
     */
    public static String toWide(String input) {
        if (input == null) {
            return null;
        }
        char[] c = input.toCharArray();
        for (int i = 0; i < c.length; i++) {
            if (c[i] == 32) {
                c[i] = (char) 12288;
                continue;
            }
            if (c[i] < 127)
                c[i] = (char) (c[i] + 65248);
        }
        return new String(c);
    }

    /**
     * 转半角的函数(DBC case) To半角字符串 全角空格为12288，半角空格为32
     * 其他字符半角(33-126)与全角(65281-65374)的对应关系是：均相差65248
     *
     * @param input
     * @return
     */
    public static String toNarrow(String input) {
        if (input == null) {
            return null;
        }
        char[] c = input.toCharArray();
        for (int i = 0; i < c.length; i++) {
            if (c[i] == 12288) {
                c[i] = (char) 32;
                continue;
            }
            if (c[i] > 65280 && c[i] < 65375)
                c[i] = (char) (c[i] - 65248);
        }
        return new String(c);
    }

    /**
     * 删除最后一个字符
     *
     * @param input
     * @return
     */
    public static String clearLastChar(String input) {
        if (input == null || input.trim().length() == 0) {
            return "";
        }
        return input.substring(0, input.length() - 1);
    }

    // static

    static Charset charsetUtf16 = Charset.forName("UTF-16");
    static Charset charsetUtf8 = Charset.forName("UTF-8");

    /**
     * ASCII表中可见字符从!开始，偏移位值为33(Decimal)
     */
    static final char DBC_CHAR_START = 33; // 半角!

    /**
     * ASCII表中可见字符到~结束，偏移位值为126(Decimal)
     */
    static final char DBC_CHAR_END = 126; // 半角~

    /**
     * 全角对应于ASCII表的可见字符从！开始，偏移值为65281
     */
    static final char SBC_CHAR_START = 65281; // 全角！

    /**
     * 全角对应于ASCII表的可见字符到～结束，偏移值为65374
     */
    static final char SBC_CHAR_END = 65374; // 全角～

    /**
     * ASCII表中除空格外的可见字符与对应的全角字符的相对偏移
     */
    static final int CONVERT_STEP = 65248; // 全角半角转换间隔

    /**
     * 全角空格的值，它没有遵从与ASCII的相对偏移，必须单独处理
     */
    static final char SBC_SPACE = 12288; // 全角空格 12288

    /**
     * 半角空格的值，在ASCII中为32(Decimal)
     */
    static final char DBC_SPACE = ' '; // 半角空格

    /**
     * <PRE>
     * 半角字符->全角字符转换
     * 只处理空格，!到&tilde;之间的字符，忽略其他
     * </PRE>
     */
    public static String bj2qj(String src) {
        if (src == null) {
            return src;
        }
        StringBuilder buf = new StringBuilder(src.length());
        char[] ca = src.toCharArray();
        for (int i = 0; i < ca.length; i++) {
            if (ca[i] == DBC_SPACE) { // 如果是半角空格，直接用全角空格替代
                buf.append(SBC_SPACE);
            } else if ((ca[i] >= DBC_CHAR_START) && (ca[i] <= DBC_CHAR_END)) { // 字符是!到~之间的可见字符
                buf.append((char) (ca[i] + CONVERT_STEP));
            } else { // 不对空格以及ascii表中其他可见字符之外的字符做任何处理
                buf.append(ca[i]);
            }
        }
        return buf.toString();
    }

    /**
     * <PRE>
     * 全角字符->半角字符转换
     * 只处理全角的空格，全角！到全角～之间的字符，忽略其他
     * </PRE>
     */
    public static String qj2bj(String src) {
        if (src == null) {
            return src;
        }
        StringBuilder buf = new StringBuilder(src.length());
        char[] ca = src.toCharArray();
        for (int i = 0; i < src.length(); i++) {
            if (ca[i] >= SBC_CHAR_START && ca[i] <= SBC_CHAR_END) { // 如果位于全角！到全角～区间内
                buf.append((char) (ca[i] - CONVERT_STEP));
            } else if (ca[i] == SBC_SPACE) { // 如果是全角空格
                buf.append(DBC_SPACE);
            } else { // 不处理全角空格，全角！到全角～区间外的字符
                buf.append(ca[i]);
            }
        }
        return buf.toString();
    }

    /**
     * 获取汉字串拼音首字母，英文字符不变
     *
     * @param chinese 汉字串
     * @return 汉语拼音首字母
     */
    public static String cn2FirstSpell(String chinese) {
        StringBuffer pybf = new StringBuffer();
        char[] arr = chinese.toCharArray();
        HanyuPinyinOutputFormat defaultFormat = new HanyuPinyinOutputFormat();
        defaultFormat.setCaseType(HanyuPinyinCaseType.LOWERCASE);
        defaultFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
        defaultFormat.setVCharType(HanyuPinyinVCharType.WITH_V);
        for (int i = 0; i < arr.length; i++) {
            if (arr[i] > 128) {
                try {
                    String[] _t = PinyinHelper.toHanyuPinyinStringArray(arr[i], defaultFormat);
                    if (_t != null) {
                        pybf.append(_t[0].charAt(0));
                    }
                } catch (BadHanyuPinyinOutputFormatCombination e) {
                    e.printStackTrace();
                }
            } else {
                pybf.append(arr[i]);
            }
        }
        return pybf.toString().replaceAll("\\W", "").trim();
    }

    /**
     * 获取汉字串拼音，英文字符不变
     *
     * @param chinese 汉字串
     * @return 汉语拼音
     */
    public static String cn2Spell(String chinese) {
        StringBuffer pybf = new StringBuffer();
        char[] arr = chinese.toCharArray();
        HanyuPinyinOutputFormat defaultFormat = new HanyuPinyinOutputFormat();
        defaultFormat.setCaseType(HanyuPinyinCaseType.LOWERCASE);
        defaultFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
        defaultFormat.setVCharType(HanyuPinyinVCharType.WITH_V);
        for (int i = 0; i < arr.length; i++) {
            if (arr[i] > 128) {
                try {
                    pybf.append(PinyinHelper.toHanyuPinyinStringArray(arr[i], defaultFormat)[0]);
                } catch (BadHanyuPinyinOutputFormatCombination e) {
                    e.printStackTrace();
                }
            } else {
                pybf.append(arr[i]);
            }
        }
        return pybf.toString();
    }

    /**
     * htmlEncode
     *
     * @param input
     * @return
     */
    public static String htmlEncode(String input) {
        return org.apache.commons.lang3.StringEscapeUtils.escapeHtml4(input);
    }

    /**
     * htmlDecode
     *
     * @param input
     * @return
     */
    public static String htmlDecode(String input) {
        return org.apache.commons.lang3.StringEscapeUtils.unescapeHtml4(input);
    }

    /**
     * urlEncode
     *
     * @param input
     * @param charset
     * @return
     */
    public static String urlEncode(String input, String charset) {
        try {
            return java.net.URLEncoder.encode(input, charset);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return input;
        }
    }

    /**
     * urlDecode
     *
     * @param input
     * @param charset
     * @return
     */
    public static String urlDecode(String input, String charset) {
        try {
            return java.net.URLDecoder.decode(input, charset);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return input;
        }
    }

    /**
     * base64Encode
     *
     * @param input
     * @param charset
     * @return
     */
    public static String encodeBase64(String input, String charset) {
        String encoded = null;
        try {
            encoded = Base64.encodeBase64String(input.getBytes(charset));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return encoded;
    }

    /**
     * base64Decode
     *
     * @param input
     * @param charset
     * @return
     */
    public static String decodeBase64(String input, String charset) {
        String encoded = null;
        try {
            encoded = new String(Base64.decodeBase64(input.getBytes(charset)));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return encoded;
    }

    /**
     * 如果A为空则显示B
     *
     * @param a
     * @param b
     * @return
     */
    public static String or(String a, String b) {
        if (StringUtils.isNotBlank(a)) {
            return a;
        }
        return b;
    }

    /**
     * 是否是空白
     *
     * @param input
     * @return
     */
    public static Boolean isBlank(String input) {
        return StringUtils.isBlank(input);
    }

    /**
     * 是否非空白
     *
     * @param input
     * @return
     */
    public static Boolean isNotBlank(String input) {
        return StringUtils.isNotBlank(input);
    }
}
